Skip to content

01 Linux 亲儿子 - Bash 或比 Python 香

Bash 和 指令的关系和区别

  • 关系
    • Bash 是一种命令行解释器,能执行用户输入的命令或存储在文件中的命令(即 Bash 脚本)。
    • Bash 脚本可以将多个复杂的命令放在一个文件中执行,实现任务自动化。
    • 理论上,所有 Bash 脚本中的操作都可以通过一系列冗长的单行命令实现,但这会导致可维护性和可读性差。
  • 区别
    • Bash 脚本:通常以文件形式存储,便于管理、修改和重用;具备更高的可读性和可维护性,支持模块化编程、条件语句和循环结构,适合复杂任务的自动化。
    • 单行命令:通常用于简单的系统管理、信息查询等操作,适合快速执行某个任务。
    • 应用场景
      • Bash 脚本广泛应用于自动化运维、批量数据处理等场景。
      • 单行命令常用于执行简单的系统信息查询、管理和维护操作。

为什么不用 Python 而用 Bash

  • 原生支持:Linux 系统默认自带 Bash,包括很多嵌入式系统,几乎所有类 Unix 系统都支持 Bash。
  • 无需额外依赖:在无网络连接等环境下,Bash 通常已经可用,适合一些网络受限的生产环境。
  • 高兼容性:Bash 与 Linux 系统紧密集成,可以直接访问和调用系统接口,如文件、进程、网络等,使用起来非常便捷。
  • 广泛应用于运维:Bash 是 Linux 运维的基础工具,许多运维脚本基于 Bash 编写,继承和复用性好。
  • 版本稳定性:Bash 的版本变化较小,较为稳定,相较于 Python 的 2.x 和 3.x 版本差异,Bash 的版本兼容性更好。
  • 与系统深度集成:在涉及系统接口的操作时,Python 实际上也是通过调用底层 Bash 命令来完成很多系统操作。

Bash 存在的劣势

  • 功能局限:缺少高级编程语言中的函数、对象、多线程等特性,数据结构支持有限(例如没有字典、复杂的列表操作等)。
  • 复杂数据处理能力不足:Bash 在处理复杂的数据结构和大型文件时性能较低,难以应对复杂的算法或数据处理任务。
  • 性能较低:相较于 C/C++ 等语言,Bash 的执行效率较低,尤其是在大规模数据处理场景下,性能可能不如 Python。
  • 可扩展性差:Bash 的可扩展性有限,难以用于复杂的脚本或大型项目开发。

Bash 还是 Python

  • 无 Python 环境:在系统没有安装 Python 或网络环境限制下无法安装时,使用 Bash
  • 简单运维脚本:例如系统监控、自动化运维等场景,Bash 通常能更简单高效地完成任务。
  • 复杂数据处理:对于需要复杂逻辑、算法和数据处理的任务,Python 更适合,具备更强的可读性、丰富的库支持和高效的数据处理能力。
  • 追求极致性能:如果任务对性能要求极高,可以考虑使用 C/C++ 这样的高效编译型语言。

总结

Linux 系统的核心是“文件”,文件几乎是系统接口的统一形式。 Bash 通过文件系统与操作系统交互,而 Python 在很多场景下也是通过调用 Bash 来操作系统文件。

Perl 与 Bash

  • Perl 的特点
    • 比 Bash 更灵活强大,支持更高级的数据类型,如正则表达式、数组、哈希表等。
    • Perl 提供了丰富的标准库和第三方库,适合更复杂的任务。
    • 在文本处理、正则表达式和字符串操作等方面,Perl 具备显著优势。
  • 使用场景
    • Perl 更适合处理复杂的数据格式、日志文件分析和文本处理任务。
    • Bash 更适合系统管理、文件操作、批处理任务等系统相关的操作。

Bash 脚本复用 - Python 调用 Bash 脚本

  • 利用 Python 的 subprocess 模块可以方便地调用 Bash 命令或脚本,适用于需要在 Python 中执行系统命令的场景。
  • subprocess 模块允许 Python 程序通过调用 Bash 实现系统任务的自动化。

Python 3 示例

python
import subprocess

def cmd_run(cmd_line, isvisible=0):
    if isvisible:
        print(f"Executing command: {cmd_line}")
    result = subprocess.run(cmd_line, shell=True, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    output = result.stdout.decode('UTF-8').strip()
    error = result.stderr.decode('UTF-8').strip()
    return [output, error]

Python 2 示例

python
import subprocess

def cmd_run(cmd_line, isvisible=0):
    if isvisible:
        print(f"Executing command: {cmd_line}")
    result = subprocess.Popen(cmd_line, shell=True, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    output = result.stdout.read().strip()
    error = result.stderr.read().strip()
    return [output, error]

说明

  • Python3 中使用 subprocess.run,返回一个 CompletedProcess 对象,包含执行结果的详细信息。
  • Python2 中使用 subprocess.Popen,需要手动读取 stdoutstderr
  • 在调用 Bash 脚本时,建议使用 shell=True,以便能够解析 Bash 的特殊字符和命令。
  • close_fds=True 确保子进程不会继承父进程的文件描述符,避免潜在的文件描述符泄漏问题。
  • decode('UTF-8', 'strict') 用于将字节流解码为字符串,'strict' 表示遇到解码错误时抛出异常。

实验代码

learn.sh

learn.sh
bash
#!/bin/bash

echo "欢迎使用学习助手!"
echo "请选择一个主题进行学习:"
echo "1. Python"
echo "2. Shell 脚本"
echo "3. Git"

read -p "请输入你的选择 (1/2/3): " choice

case $choice in
    1)
        echo "你选择了学习 Python。"
        echo "Python 是一种强大的编程语言,适用于各种应用场景。"
        ;;
    2)
        echo "你选择了学习 Shell 脚本。"
        echo "Shell 脚本是一种用于自动化任务的脚本语言。"
        ;;
    3)
        echo "你选择了学习 Git。"
        echo "Git 是一个分布式版本控制系统,用于跟踪文件的变化。"
        ;;
    *)
        echo "无效的选择,请输入 1、2 或 3。"
        ;;
esac

call_learn.py

call_learn.py
python
import subprocess
import sys

def run_shell_script():
    print("正在启动学习助手...")

    # 检查是否有命令行参数
    if len(sys.argv) > 1:
        choice = sys.argv[1]
    else:
        # 如果没有命令行参数,则获取用户输入
        choice = input()

    # 运行 shell 脚本,传入用户的选择
    process = subprocess.run(['./learn.sh'],
                             input=choice,
                             capture_output=True,
                             text=True)

    # 打印 shell 脚本的输出
    print(process.stdout)

    # 检查是否有错误
    if process.stderr:
        print("错误:", process.stderr)

if __name__ == "__main__":
    run_shell_script()

运行 learn.sh 脚本

运行 learn.sh 脚本
bash
  linux_demo vim learn.sh
  linux_demo chmod +x learn.sh
  linux_demo bash learn.sh
欢迎使用学习助手!
请选择一个主题进行学习:
1. Python
2. Shell 脚本
3. Git
请输入你的选择 (1/2/3): 2
你选择了学习 Shell 脚本。
Shell 脚本是一种用于自动化任务的脚本语言。
  linux_demo bash learn.sh
欢迎使用学习助手!
请选择一个主题进行学习:
1. Python
2. Shell 脚本
3. Git
请输入你的选择 (1/2/3): 1
你选择了学习 Python。
Python 是一种强大的编程语言,适用于各种应用场景。

运行 call_learn.py 脚本

运行 call_learn.py 脚本
bash
  linux_demo vim call_learn.py
  linux_demo python call_learn.py
正在启动学习助手...
1
欢迎使用学习助手!
请选择一个主题进行学习:
1. Python
2. Shell 脚本
3. Git
你选择了学习 Python。
Python 是一种强大的编程语言,适用于各种应用场景。

  linux_demo python call_learn.py
正在启动学习助手...
2
欢迎使用学习助手!
请选择一个主题进行学习:
1. Python
2. Shell 脚本
3. Git
你选择了学习 Shell 脚本。
Shell 脚本是一种用于自动化任务的脚本语言。

  linux_demo python call_learn.py 3
正在启动学习助手...
欢迎使用学习助手!
请选择一个主题进行学习:
1. Python
2. Shell 脚本
3. Git
你选择了学习 Git。
Git 是一个分布式版本控制系统,用于跟踪文件的变化。